#include "mime_type.h"
#include <unordered_map>
#include <string_view>
#include <string>

using namespace ::std::string_view_literals;

namespace wilson::util
{
    ::std::string_view 
    get_mime_type(const ::std::filesystem::path& file_name)
    {
        static const auto mime_map = []{
            ::std::unordered_map<
                ::std::string_view, 
                ::std::string_view
            > ret;
            ret[".*"]       = "application/octet-stream"sv;
            ret[".acp"]     = "audio/x-mei-aac"sv;
            ret[".aif"]     = "audio/aiff"sv;
            ret[".aiff"]    = "audio/aiff"sv;
            ret[".asa"]     = "text/asa"sv;
            ret[".asp"]     = "text/asp"sv;
            ret[".au"]      = "audio/basic"sv;
            ret[".awf"]     = "application/vnd.adobe.workflow"sv;
            ret[".bmp"]     = "application/x-bmp"sv;
            ret[".c4t"]     = "application/x-c4t"sv;
            ret[".cal"]     = "application/x-cals"sv;
            ret[".cdf"]     = "application/x-netcdf"sv;
            ret[".cel"]     = "application/x-cel"sv;
            ret[".cg4"]     = "application/x-g4"sv;
            ret[".cit"]     = "application/x-cit"sv;
            ret[".cml"]     = "text/xml"sv;
            ret[".cmx"]     = "application/x-cmx"sv;
            ret[".crl"]     = "application/pkix-crl"sv;
            ret[".csi"]     = "application/x-csi"sv;
            ret[".cut"]     = "application/x-cut"sv;
            ret[".dbm"]     = "application/x-dbm"sv;
            ret[".dcd"]     = "text/xml"sv;
            ret[".der"]     = "application/x-x509-ca-cert"sv;
            ret[".dib"]     = "application/x-dib"sv;
            ret[".doc"]     = "application/msword"sv;
            ret[".drw"]     = "application/x-drw"sv;
            ret[".dwf"]     = "Model/vnd.dwf"sv;
            ret[".dwg"]     = "application/x-dwg"sv;
            ret[".dxf"]     = "application/x-dxf"sv;
            ret[".emf"]     = "application/x-emf"sv;
            ret[".ent"]     = "text/xml"sv;
            ret[".eps"]     = "application/x-ps"sv;
            ret[".etd"]     = "application/x-ebx"sv;
            ret[".fax"]     = "image/fax"sv;
            ret[".fif"]     = "application/fractals"sv;
            ret[".frm"]     = "application/x-frm"sv;
            ret[".gbr"]     = "application/x-gbr"sv;
            ret[".gif"]     = "image/gif"sv;
            ret[".gp4"]     = "application/x-gp4"sv;
            ret[".hmr"]     = "application/x-hmr"sv;
            ret[".hpl"]     = "application/x-hpl"sv;
            ret[".hrf"]     = "application/x-hrf"sv;
            ret[".htc"]     = "text/x-component"sv;
            ret[".html"]    = "text/html"sv;
            ret[".htx"]     = "text/html"sv;
            ret[".ico"]     = "image/x-icon"sv;
            ret[".iff"]     = "application/x-iff"sv;
            ret[".igs"]     = "application/x-igs"sv;
            ret[".img"]     = "application/x-img"sv;
            ret[".isp"]     = "application/x-internet-signup"sv;
            ret[".java"]    = "java/*"sv;
            ret[".jpe"]     = "image/jpeg"sv;
            ret[".jpeg"]    = "image/jpeg"sv;
            ret[".jpg"]     = "application/x-jpg"sv;
            ret[".jsp"]     = "text/html"sv;
            ret[".lar"]     = "application/x-laplayer-reg"sv;
            ret[".lavs"]    = "audio/x-liquid-secure"sv;
            ret[".lmsff"]   = "audio/x-la-lms"sv;
            ret[".ltr"]     = "application/x-ltr"sv;
            ret[".m2v"]     = "video/x-mpeg"sv;
            ret[".m4e"]     = "video/mpeg4"sv;
            ret[".man"]     = "application/x-troff-man"sv;
            ret[".mdb"]     = "application/msaccess"sv;
            ret[".mfp"]     = "application/x-shockwave-flash"sv;
            ret[".mhtml"]   = "message/rfc822"sv;
            ret[".mid"]     = "audio/mid"sv;
            ret[".mil"]     = "application/x-mil"sv;
            ret[".mnd"]     = "audio/x-musicnet-download"sv;
            ret[".mocha"]   = "application/x-javascript"sv;
            ret[".mp1"]     = "audio/mp1"sv;
            ret[".mp2v"]    = "video/mpeg"sv;
            ret[".mp4"]     = "video/mpeg4"sv;
            ret[".mpd"]     = "application/vnd.ms-project"sv;
            ret[".mpeg"]    = "video/mpg"sv;
            ret[".mpga"]    = "audio/rn-mpeg"sv;
            ret[".mps"]     = "video/x-mpeg"sv;
            ret[".mpv"]     = "video/mpg"sv;
            ret[".mpw"]     = "application/vnd.ms-project"sv;
            ret[".mtx"]     = "text/xml"sv;
            ret[".net"]     = "image/pnetvue"sv;
            ret[".nws"]     = "message/rfc822"sv;
            ret[".out"]     = "application/x-out"sv;
            ret[".p12"]     = "application/x-pkcs12"sv;
            ret[".p7c"]     = "application/pkcs7-mime"sv;
            ret[".p7r"]     = "application/x-pkcs7-certreqresp"sv;
            ret[".pc5"]     = "application/x-pc5"sv;
            ret[".pcl"]     = "application/x-pcl"sv;
            ret[".pdf"]     = "application/pdf"sv;
            ret[".pdx"]     = "application/vnd.adobe.pdx"sv;
            ret[".pgl"]     = "application/x-pgl"sv;
            ret[".pko"]     = "application/vnd.ms-pki.pko"sv;
            ret[".plg"]     = "text/html"sv;
            ret[".plt"]     = "application/x-plt"sv;
            ret[".png"]     = "application/x-png"sv;
            ret[".ppa"]     = "application/vnd.ms-powerpoint"sv;
            ret[".pps"]     = "application/vnd.ms-powerpoint"sv;
            ret[".ppt"]     = "application/x-ppt"sv;
            ret[".prf"]     = "application/pics-rules"sv;
            ret[".prt"]     = "application/x-prt"sv;
            ret[".ps"]      = "application/postscript"sv;
            ret[".pwz"]     = "application/vnd.ms-powerpoint"sv;
            ret[".ra"]      = "audio/vnd.rn-realaudio"sv;
            ret[".ras"]     = "application/x-ras"sv;
            ret[".rdf"]     = "text/xml"sv;
            ret[".red"]     = "application/x-red"sv;
            ret[".rjs"]     = "application/vnd.rn-realsystem-rjs"sv;
            ret[".rlc"]     = "application/x-rlc"sv;
            ret[".rm"]      = "application/vnd.rn-realmedia"sv;
            ret[".rmi"]     = "audio/mid"sv;
            ret[".rmm"]     = "audio/x-pn-realaudio"sv;
            ret[".rms"]     = "application/vnd.rn-realmedia-secure"sv;
            ret[".rmx"]     = "application/vnd.rn-realsystem-rmx"sv;
            ret[".rp"]      = "image/vnd.rn-realpix"sv;
            ret[".rsml"]    = "application/vnd.rn-rsml"sv;
            ret[".rtf"]     = "application/msword"sv;
            ret[".rv"]      = "video/vnd.rn-realvideo"sv;
            ret[".sat"]     = "application/x-sat"sv;
            ret[".sdw"]     = "application/x-sdw"sv;
            ret[".slb"]     = "application/x-slb"sv;
            ret[".slk"]     = "drawing/x-slk"sv;
            ret[".smil"]    = "application/smil"sv;
            ret[".snd"]     = "audio/basic"sv;
            ret[".sor"]     = "text/plain"sv;
            ret[".spl"]     = "application/futuresplash"sv;
            ret[".ssm"]     = "application/streamingmedia"sv;
            ret[".stl"]     = "application/vnd.ms-pki.stl"sv;
            ret[".sty"]     = "application/x-sty"sv;
            ret[".swf"]     = "application/x-shockwave-flash"sv;
            ret[".tg4"]     = "application/x-tg4"sv;
            ret[".tif"]     = "image/tiff"sv;
            ret[".tiff"]    = "image/tiff"sv;
            ret[".top"]     = "drawing/x-top"sv;
            ret[".tsd"]     = "text/xml"sv;
            ret[".uin"]     = "application/x-icq"sv;
            ret[".vcf"]     = "text/x-vcard"sv;
            ret[".vdx"]     = "application/vnd.visio"sv;
            ret[".vpg"]     = "application/x-vpeg005"sv;
            ret[".vsd"]     = "application/x-vsd"sv;
            ret[".vst"]     = "application/vnd.visio"sv;
            ret[".vsw"]     = "application/vnd.visio"sv;
            ret[".vtx"]     = "application/vnd.visio"sv;
            ret[".wav"]     = "audio/wav"sv;
            ret[".wb1"]     = "application/x-wb1"sv;
            ret[".wb3"]     = "application/x-wb3"sv;
            ret[".wiz"]     = "application/msword"sv;
            ret[".wk4"]     = "application/x-wk4"sv;
            ret[".wks"]     = "application/x-wks"sv;
            ret[".wma"]     = "audio/x-ms-wma"sv;
            ret[".wmf"]     = "application/x-wmf"sv;
            ret[".wmv"]     = "video/x-ms-wmv"sv;
            ret[".wmz"]     = "application/x-ms-wmz"sv;
            ret[".wpd"]     = "application/x-wpd"sv;
            ret[".wpl"]     = "application/vnd.ms-wpl"sv;
            ret[".wr1"]     = "application/x-wr1"sv;
            ret[".wrk"]     = "application/x-wrk"sv;
            ret[".ws2"]     = "application/x-ws"sv;
            ret[".wsdl"]    = "text/xml"sv;
            ret[".xdp"]     = "application/vnd.adobe.xdp"sv;
            ret[".xfd"]     = "application/vnd.adobe.xfd"sv;
            ret[".xhtml"]   = "text/html"sv;
            ret[".xls"]     = "application/x-xls"sv;
            ret[".xml"]     = "text/xml"sv;
            ret[".xq"]      = "text/xml"sv;
            ret[".xquery"]  = "text/xml"sv;
            ret[".xsl"]     = "text/xml"sv;
            ret[".xwd"]     = "application/x-xwd"sv;
            ret[".sis"]     = "application/vnd.symbian.install"sv;
            ret[".x_t"]     = "application/x-x_t"sv;
            ret[".apk"]     = "application/vnd.android.package-archive"sv;
            ret[".tif"]     = "image/tiff";
            ret[".a11"]     = "application/x-a11"sv;
            ret[".ai"]      = "application/postscript"sv;
            ret[".aifc"]    = "audio/aiff"sv;
            ret[".anv"]     = "application/x-anv"sv;
            ret[".asf"]     = "video/x-ms-asf"sv;
            ret[".asx"]     = "video/x-ms-asf"sv;
            ret[".avi"]     = "video/avi"sv;
            ret[".biz"]     = "text/xml"sv;
            ret[".bot"]     = "application/x-bot"sv;
            ret[".c90"]     = "application/x-c90"sv;
            ret[".cat"]     = "application/vnd.ms-pki.seccat"sv;
            ret[".cdr"]     = "application/x-cdr"sv;
            ret[".cer"]     = "application/x-x509-ca-cert"sv;
            ret[".cgm"]     = "application/x-cgm"sv;
            ret[".class"]   = "java/*"sv;
            ret[".cmp"]     = "application/x-cmp"sv;
            ret[".cot"]     = "application/x-cot"sv;
            ret[".crt"]     = "application/x-x509-ca-cert"sv;
            ret[".css"]     = "text/css"sv;
            ret[".dbf"]     = "application/x-dbf"sv;
            ret[".dbx"]     = "application/x-dbx"sv;
            ret[".dcx"]     = "application/x-dcx"sv;
            ret[".dgn"]     = "application/x-dgn"sv;
            ret[".dll"]     = "application/x-msdownload"sv;
            ret[".dot"]     = "application/msword"sv;
            ret[".dtd"]     = "text/xml"sv;
            ret[".dwf"]     = "application/x-dwf"sv;
            ret[".dxb"]     = "application/x-dxb"sv;
            ret[".edn"]     = "application/vnd.adobe.edn"sv;
            ret[".eml"]     = "message/rfc822"sv;
            ret[".epi"]     = "application/x-epi"sv;
            ret[".eps"]     = "application/postscript"sv;
            ret[".exe"]     = "application/x-msdownload"sv;
            ret[".fdf"]     = "application/vnd.fdf"sv;
            ret[".fo"]      = "text/xml"sv;
            ret[".g4"]      = "application/x-g4"sv;
            ret["."]        = "application/x-"sv;
            ret[".gl2"]     = "application/x-gl2"sv;
            ret[".hgl"]     = "application/x-hgl"sv;
            ret[".hpg"]     = "application/x-hpgl"sv;
            ret[".hqx"]     = "application/mac-binhex40"sv;
            ret[".hta"]     = "application/hta"sv;
            ret[".htm"]     = "text/html"sv;
            ret[".htt"]     = "text/webviewhtml"sv;
            ret[".icb"]     = "application/x-icb"sv;
            ret[".ico"]     = "application/x-ico"sv;
            ret[".ig4"]     = "application/x-g4"sv;
            ret[".iii"]     = "application/x-iphone"sv;
            ret[".ins"]     = "application/x-internet-signup"sv;
            ret[".IVF"]     = "video/x-ivf"sv;
            ret[".jfif"]    = "image/jpeg"sv;
            ret[".jpe"]     = "application/x-jpe"sv;
            ret[".jpg"]     = "image/jpeg"sv;
            ret[".js"]      = "application/x-javascript"sv;
            ret[".la1"]     = "audio/x-liquid-file"sv;
            ret[".latex"]   = "application/x-latex"sv;
            ret[".lbm"]     = "application/x-lbm"sv;
            ret[".ls"]      = "application/x-javascript"sv;
            ret[".m1v"]     = "video/x-mpeg"sv;
            ret[".m3u"]     = "audio/mpegurl"sv;
            ret[".mac"]     = "application/x-mac"sv;
            ret[".math"]    = "text/xml"sv;
            ret[".mdb"]     = "application/x-mdb"sv;
            ret[".mht"]     = "message/rfc822"sv;
            ret[".mi"]      = "application/x-mi"sv;
            ret[".midi"]    = "audio/mid"sv;
            ret[".mml"]     = "text/xml"sv;
            ret[".mns"]     = "audio/x-musicnet-stream"sv;
            ret[".movie"]   = "video/x-sgi-movie"sv;
            ret[".mp2"]     = "audio/mp2"sv;
            ret[".mp3"]     = "audio/mp3"sv;
            ret[".mpa"]     = "video/x-mpg"sv;
            ret[".mpe"]     = "video/x-mpeg"sv;
            ret[".mpg"]     = "video/mpg"sv;
            ret[".mpp"]     = "application/vnd.ms-project"sv;
            ret[".mpt"]     = "application/vnd.ms-project"sv;
            ret[".mpv2"]    = "video/mpeg"sv;
            ret[".mpx"]     = "application/vnd.ms-project"sv;
            ret[".mxp"]     = "application/x-mmxp"sv;
            ret[".nrf"]     = "application/x-nrf"sv;
            ret[".odc"]     = "text/x-ms-odc"sv;
            ret[".p10"]     = "application/pkcs10"sv;
            ret[".p7b"]     = "application/x-pkcs7-certificates"sv;
            ret[".p7m"]     = "application/pkcs7-mime"sv;
            ret[".p7s"]     = "application/pkcs7-signature"sv;
            ret[".pci"]     = "application/x-pci"sv;
            ret[".pcx"]     = "application/x-pcx"sv;
            ret[".pdf"]     = "application/pdf"sv;
            ret[".pfx"]     = "application/x-pkcs12"sv;
            ret[".pic"]     = "application/x-pic"sv;
            ret[".pl"]      = "application/x-perl"sv;
            ret[".pls"]     = "audio/scpls"sv;
            ret[".png"]     = "image/png"sv;
            ret[".pot"]     = "application/vnd.ms-powerpoint"sv;
            ret[".ppm"]     = "application/x-ppm"sv;
            ret[".ppt"]     = "application/vnd.ms-powerpoint"sv;
            ret[".pr"]      = "application/x-pr"sv;
            ret[".prn"]     = "application/x-prn"sv;
            ret[".ps"]      = "application/x-ps"sv;
            ret[".ptn"]     = "application/x-ptn"sv;
            ret[".r3t"]     = "text/vnd.rn-realtext3d"sv;
            ret[".ram"]     = "audio/x-pn-realaudio"sv;
            ret[".rat"]     = "application/rat-file"sv;
            ret[".rec"]     = "application/vnd.rn-recording"sv;
            ret[".rgb"]     = "application/x-rgb"sv;
            ret[".rjt"]     = "application/vnd.rn-realsystem-rjt"sv;
            ret[".rle"]     = "application/x-rle"sv;
            ret[".rmf"]     = "application/vnd.adobe.rmf"sv;
            ret[".rmj"]     = "application/vnd.rn-realsystem-rmj"sv;
            ret[".rmp"]     = "application/vnd.rn-rn_music_package"sv;
            ret[".rmvb"]    = "application/vnd.rn-realmedia-vbr"sv;
            ret[".rnx"]     = "application/vnd.rn-realplayer"sv;
            ret[".rpm"]     = "audio/x-pn-realaudio-plugin"sv;
            ret[".rt"]      = "text/vnd.rn-realtext"sv;
            ret[".rtf"]     = "application/x-rtf"sv;
            ret[".sam"]     = "application/x-sam"sv;
            ret[".sdp"]     = "application/sdp"sv;
            ret[".sit"]     = "application/x-stuffit"sv;
            ret[".sld"]     = "application/x-sld"sv;
            ret[".smi"]     = "application/smil"sv;
            ret[".smk"]     = "application/x-smk"sv;
            ret[".sol"]     = "text/plain"sv;
            ret[".spc"]     = "application/x-pkcs7-certificates"sv;
            ret[".spp"]     = "text/xml"sv;
            ret[".sst"]     = "application/vnd.ms-pki.certstore"sv;
            ret[".stm"]     = "text/html"sv;
            ret[".svg"]     = "text/xml"sv;
            ret[".tdf"]     = "application/x-tdf"sv;
            ret[".tga"]     = "application/x-tga"sv;
            ret[".tif"]     = "application/x-tif"sv;
            ret[".tld"]     = "text/xml"sv;
            ret[".torrent"] = "application/x-bittorrent"sv;
            ret[".txt"]     = "text/plain"sv;
            ret[".uls"]     = "text/iuls"sv;
            ret[".vda"]     = "application/x-vda"sv;
            ret[".vml"]     = "text/xml"sv;
            ret[".vsd"]     = "application/vnd.visio"sv;
            ret[".vss"]     = "application/vnd.visio"sv;
            ret[".vst"]     = "application/x-vst"sv;
            ret[".vsx"]     = "application/vnd.visio"sv;
            ret[".vxml"]    = "text/xml"sv;
            ret[".wax"]     = "audio/x-ms-wax"sv;
            ret[".wb2"]     = "application/x-wb2"sv;
            ret[".wbmp"]    = "image/vnd.wap.wbmp"sv;
            ret[".wk3"]     = "application/x-wk3"sv;
            ret[".wkq"]     = "application/x-wkq"sv;
            ret[".wm"]      = "video/x-ms-wm"sv;
            ret[".wmd"]     = "application/x-ms-wmd"sv;
            ret[".wml"]     = "text/vnd.wap.wml"sv;
            ret[".wmx"]     = "video/x-ms-wmx"sv;
            ret[".wp6"]     = "application/x-wp6"sv;
            ret[".wpg"]     = "application/x-wpg"sv;
            ret[".wq1"]     = "application/x-wq1"sv;
            ret[".wri"]     = "application/x-wri"sv;
            ret[".ws"]      = "application/x-ws"sv;
            ret[".wsc"]     = "text/scriptlet"sv;
            ret[".wvx"]     = "video/x-ms-wvx"sv;
            ret[".xdr"]     = "text/xml"sv;
            ret[".xfdf"]    = "application/vnd.adobe.xfdf"sv;
            ret[".xls"]     = "application/vnd.ms-excel"sv;
            ret[".xlw"]     = "application/x-xlw"sv;
            ret[".xpl"]     = "audio/scpls"sv;
            ret[".xql"]     = "text/xml"sv;
            ret[".xsd"]     = "text/xml"sv;
            ret[".xslt"]    = "text/xml"sv;
            ret[".x_b"]     = "application/x-x_b"sv;
            ret[".sisx"]    = "application/vnd.symbian.install"sv;
            ret[".ipa"]     = "application/vnd.iphone"sv;
            ret[".xap"]     = "application/x-silverlight-app"sv;

            return ret;
        }();
        auto extension = file_name.extension();
        if (!extension.empty())
        {
            auto ret_iter = mime_map.find(::std::string{ extension });
            if (ret_iter != mime_map.cend())
                return ret_iter->second;
        }
        return "application/octet-stream"sv;
    }
    
    ::std::string_view get_mime_type(const ::std::string& path) 
    {
        return get_mime_type(::std::filesystem::path{ path });
    }
}
